package com.kotodama.application.service.validation;

import com.kotodama.application.dto.validation.TenantValidationDto;
import com.kotodama.domain.entities.Tenant;
import com.kotodama.domain.enums.TenantStatus;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validator;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 租户验证服务
 * 使用Bean Validation + 自定义业务规则验证
 * 替换Drools规则引擎
 */
@Service
public class TenantValidationService {

    private final Validator validator;

    public TenantValidationService(Validator validator) {
        this.validator = validator;
    }

    /**
     * 验证租户创建
     */
    public ValidationResult validateTenantCreation(Tenant tenant) {
        ValidationResult result = new ValidationResult();

        // Bean Validation基础验证
        TenantValidationDto dto = new TenantValidationDto(
                tenant.getName() != null ? tenant.getName().getValue() : null,
                tenant.getStatus());
        dto.setOperation("CREATE");

        Set<ConstraintViolation<TenantValidationDto>> violations = validator.validate(dto);
        for (ConstraintViolation<TenantValidationDto> violation : violations) {
            result.addError(violation.getMessage());
        }

        // 自定义业务规则验证
        validateCreationBusinessRules(tenant, result);

        return result;
    }

    /**
     * 验证租户状态变更
     */
    public ValidationResult validateStatusChange(Tenant tenant, TenantStatus newStatus) {
        ValidationResult result = new ValidationResult();

        // 状态变更业务规则验证
        validateStatusChangeBusinessRules(tenant, newStatus, result);

        return result;
    }

    /**
     * 验证租户删除
     */
    public ValidationResult validateTenantDeletion(Tenant tenant) {
        ValidationResult result = new ValidationResult();

        // 删除业务规则验证
        validateDeletionBusinessRules(tenant, result);

        return result;
    }

    /**
     * 租户创建业务规则验证
     */
    private void validateCreationBusinessRules(Tenant tenant, ValidationResult result) {
        // 检查初始状态
        if (tenant.getStatus() != TenantStatus.INACTIVE) {
            result.addWarning("新创建的租户状态应为INACTIVE");
        }
    }

    /**
     * 状态变更业务规则验证
     */
    private void validateStatusChangeBusinessRules(Tenant tenant, TenantStatus newStatus, ValidationResult result) {
        if (!isValidStatusTransition(tenant.getStatus(), newStatus)) {
            result.addError("无效的状态变更：从 " + tenant.getStatus() + " 到 " + newStatus);
        }
    }

    /**
     * 删除业务规则验证
     */
    private void validateDeletionBusinessRules(Tenant tenant, ValidationResult result) {
        if (tenant.getStatus() == TenantStatus.ACTIVE) {
            result.addError("无法删除活跃状态的租户，请先将状态更改为INACTIVE");
        } else if (tenant.getStatus() == TenantStatus.SUSPENDED) {
            result.addWarning("删除暂停状态的租户，请确认是否有未处理的数据");
        }
    }

    /**
     * 检查状态变更是否有效
     */
    private boolean isValidStatusTransition(TenantStatus currentStatus, TenantStatus newStatus) {
        if (currentStatus == null || newStatus == null) {
            return false;
        }

        return switch (currentStatus) {
            case INACTIVE -> newStatus == TenantStatus.ACTIVE;
            case ACTIVE -> newStatus == TenantStatus.SUSPENDED;
            case SUSPENDED -> newStatus == TenantStatus.ACTIVE || newStatus == TenantStatus.INACTIVE;
        };
    }

    /**
     * 验证结果类
     */
    public static class ValidationResult {
        private boolean valid = true;
        private final List<String> errors = new ArrayList<>();
        private final List<String> warnings = new ArrayList<>();

        public boolean isValid() {
            return valid && errors.isEmpty();
        }

        public void setValid(boolean valid) {
            this.valid = valid;
        }

        public List<String> getErrors() {
            return errors;
        }

        public void addError(String error) {
            this.errors.add(error);
            this.valid = false;
        }

        public List<String> getWarnings() {
            return warnings;
        }

        public void addWarning(String warning) {
            this.warnings.add(warning);
        }

        public boolean hasErrors() {
            return !errors.isEmpty();
        }

        public boolean hasWarnings() {
            return !warnings.isEmpty();
        }
    }
}